import { DeleteOutlined } from '@ant-design/icons'
import { Button, Table, Tabs } from 'antd'
import { connect } from 'dva'
import { isArray, isEmpty } from 'lodash-es'
import { useEffect, useState } from 'react'

import { deleteMenuApi, queryMenuFunctionApi, saveMenuApi } from '@/api/sys/menuManage'
import AekButton from '@/components/AekButton'
import AekForm from '@/components/AekForm'
import AekSpin from '@/components/AekSpin'
import AekTree from '@/components/AekTree'
import APanel from '@/components/APanel'
import Ellipsis from '@/components/Ellipsis'
import PageLayout from '@/components/PageLayout'
import { namespace } from '@/models/sys/menuManage'
import { message, modal, renderIndexColumn } from '@/utils/antdHelper'
import { getBasicFn } from '@/utils/dvaUtil/index'
import { requestWithTry } from '@/utils/request'

import AddModal from './components/AddModal'

/** 系统-菜单管理 */
const Index = ({ modelState, loading }) => {
  const [form] = AekForm.useForm()
  const featureId = AekForm.useWatch('featureId', form)
  const { entranceList } = modelState
  const { toAction, getLoading } = getBasicFn({ namespace, loading })

  const [selectedEntrance, setSelectedEntrance] = useState({})
  const [menuInfo, setMenuInfo] = useState({})
  const [features, setFeatures] = useState([])

  useEffect(() => {
    if (!entranceList.length) return
    if (!isEmpty(selectedEntrance)) {
      const oldEntrance = entranceList.find(({ entranceId }) => entranceId === selectedEntrance.entranceId)
      setSelectedEntrance({
        ...oldEntrance,
        menuList: renameChildrenConditionally(oldEntrance?.menuList),
      })
      return
    }
    const firstEntrance = entranceList[0]
    setSelectedEntrance({
      ...firstEntrance,
      menuList: renameChildrenConditionally(firstEntrance?.menuList),
    })
  }, [entranceList])

  const onActiveKeyChange = activeKey => {
    const entrance = entranceList.find(item => item?.entranceId === activeKey)
    entrance.menuList = renameChildrenConditionally(entrance.menuList)
    setSelectedEntrance(entrance)
  }

  const addMenu = async () => {
    await AddModal.PromiseThen({
      tree: selectedEntrance?.menuList || [],
      features,
      entranceId: selectedEntrance.entranceId,
    })
    message.success('保存成功')
    toAction('getTreeMenu')
  }

  const delMenu = async item => {
    modal.confirm({
      title: '删除',
      content: `确认删除菜单【${item.menuName}】？`,
      onOk: async () => {
        await requestWithTry(deleteMenuApi, { menuId: item.menuId })
        message.success('删除成功')
        toAction('getTreeMenu')
      },
    })
  }

  useEffect(() => {
    if (!selectedEntrance.entranceId) return
    const { entranceId } = selectedEntrance
    requestWithTry(queryMenuFunctionApi, { entranceId }).then(res => {
      setFeatures(res.data)
    })
  }, [selectedEntrance.entranceId])

  const save = async () => {
    const data = await form.validateFields()
    await requestWithTry(saveMenuApi, {
      ...data,
      entranceId: selectedEntrance.entranceId,
      menuId: menuInfo.menuId,
      icon: data.icon?.[0]?.url,
      highlightIcon: data.highlightIcon?.[0]?.url,
      operationList: features
        .find(item => item.featureId === featureId)
        ?.operationList?.map((item, index) => ({
          index: index + 1,
          featureName: item.featureName,
        })),
    })
    message.success('保存成功')
    toAction('getTreeMenu')
  }

  function renameChildrenConditionally(arr) {
    if (!isArray(arr)) return []
    for (const obj of arr) {
      if (Array.isArray(obj.children)) {
        // 检查当前children数组的所有子元素是否全为type:1
        const permission = obj.children?.filter(child => child.type === 1)
        const childrenWithoutPermission = obj.children?.filter(child => child.type === 0)
        if (permission) {
          // 重命名字段为permission，并停止递归该子数组
          obj.permission = permission
          obj.children = childrenWithoutPermission
        }
        // 继续递归处理未满足条件的children子元素
        renameChildrenConditionally(obj.children)
      }
    }
    return arr
  }

  /** @type {import("@/components/AekTree").AekTreeProps} */
  const treeProps = {
    treeData: selectedEntrance?.menuList || [],
    fieldNames: {
      key: 'menuId',
      title: 'menuName',
    },
    canCancelSel: false,
    defaultSelectFirst: true,
    onSelect: (_, { node }) => {
      setMenuInfo(node)
      form.setFieldsValue({
        parentMenuName: undefined,
        menuName: undefined,
        path: undefined,
        featureId: undefined,
        icon: undefined,
        highlightIcon: undefined,
        ...node,
      })
    },
    titleRender: item => (
      <div className={`group flex`}>
        <Ellipsis>{item.menuName}</Ellipsis>
        <div
          className={`ml20px hidden flex-none group-hover:block`}
          onClick={e => {
            e.stopPropagation?.()
          }}
        >
          <DeleteOutlined className='ml10px c-del' type='delete' onClick={() => delMenu(item)} />
        </div>
      </div>
    ),
  }

  /** @type {import("@/components/AekForm").FormDataProps[]} */
  const formData = [
    {
      field: 'parentMenuName',
      label: '父菜单',
      component: { name: 'Input' },
      view: true,
      viewRender: text => text || '全部',
    },
    {
      field: 'menuName',
      label: '菜单名称',
      formItemProps: {
        rules: [{ required: true }],
      },
      component: { name: 'Input' },
    },
    {
      field: 'path',
      label: '路径名',
      formItemProps: {
        rules: [{ required: true }],
      },
      component: { name: 'Input' },
    },
    {
      field: 'featureId',
      label: '功能页面',
      component: {
        name: 'Select',
        props: { options: features.map(item => ({ value: item.featureId, label: item.featureName })) },
      },
    },
    {
      field: 'icon',
      label: '图标（普通）',
      component: { name: 'AekUpload', props: { fileType: 'img', listType: 'picture-card', limitFileNum: 1 } },
    },
    {
      field: 'highlightIcon',
      label: '图标（高亮）',
      component: { name: 'AekUpload', props: { fileType: 'img', listType: 'picture-card', limitFileNum: 1 } },
    },
    {
      field: 'operationList',
      label: '界面权限列表',
      component: (
        <Table
          rowKey='featureName'
          dataSource={features.find(item => item.featureId === featureId)?.operationList || []}
          pagination={false}
          columns={[
            renderIndexColumn(),
            {
              title: '功能名称',
              dataIndex: 'featureName',
            },
          ]}
        />
      ),
    },
  ]

  return (
    <PageLayout>
      <Tabs
        activeKey={selectedEntrance?.entranceId}
        onChange={onActiveKeyChange}
        className='mb8px'
        items={entranceList.map(item => ({
          key: item?.entranceId,
          label: item.entranceName,
        }))}
      />
      <PageLayout.Columns>
        <PageLayout.LeftColumn>
          <Button type='primary' block className='mb10px flex-none' onClick={addMenu}>
            新增菜单
          </Button>
          <div className='flex-grow-1 overflow-y-auto'>
            <AekTree {...treeProps} />
          </div>
        </PageLayout.LeftColumn>
        <PageLayout.RightColumn>
          <AekSpin spinning={getLoading('getTreeMenu')}>
            <APanel
              key='title'
              title={menuInfo.menuName}
              extra={
                <AekButton type='primary' onSubmit={save}>
                  保存
                </AekButton>
              }
            />
            <div className='overflow-y-auto overflow-x-hidden' style={{ height: 'calc(100vh - 250px)' }}>
              <AekForm form={form} formData={formData} detail={menuInfo} layout={['150px', '0.8']} />
            </div>
          </AekSpin>
        </PageLayout.RightColumn>
      </PageLayout.Columns>
    </PageLayout>
  )
}

export default connect(store => ({
  modelState: store[namespace],
  loading: store.loading,
}))(Index)
